﻿using Abp.Authorization;
using Abp.Configuration.Startup;
using Abp.Localization;
using Abp.MultiTenancy;

namespace ARchGL.Platform.Authorization
{
    /// <summary>
    /// Application's authorization provider.
    /// Defines permissions for the application.
    /// See <see cref="AppPermissions"/> for all permission names.
    /// </summary>
    public class AppAuthorizationProvider : AuthorizationProvider
    {
        private readonly bool _isMultiTenancyEnabled;

        public AppAuthorizationProvider(bool isMultiTenancyEnabled)
        {
            _isMultiTenancyEnabled = isMultiTenancyEnabled;
        }

        public AppAuthorizationProvider(IMultiTenancyConfig multiTenancyConfig)
        {
            _isMultiTenancyEnabled = multiTenancyConfig.IsEnabled;
        }

        public override void SetPermissions(IPermissionDefinitionContext context)
        {
            #region 系统现有权限

            //COMMON PERMISSIONS (FOR BOTH OF TENANTS AND HOST)

            var pages = context.GetPermissionOrNull(AppPermissions.Pages) ?? context.CreatePermission(AppPermissions.Pages, L("Pages"));
            pages.CreateChildPermission(AppPermissions.Pages_DemoUiComponents, L("DemoUiComponents"));

            var administration = pages.CreateChildPermission(AppPermissions.Pages_Administration, L("Administration"));

            var roles = administration.CreateChildPermission(AppPermissions.Pages_Administration_Roles, L("Roles"));
            roles.CreateChildPermission(AppPermissions.Pages_Administration_Roles_Create, L("CreatingNewRole"));
            roles.CreateChildPermission(AppPermissions.Pages_Administration_Roles_Edit, L("EditingRole"));
            roles.CreateChildPermission(AppPermissions.Pages_Administration_Roles_Delete, L("DeletingRole"));

            var users = administration.CreateChildPermission(AppPermissions.Pages_Administration_Users, L("Users"));
            users.CreateChildPermission(AppPermissions.Pages_Administration_Users_Create, L("CreatingNewUser"));
            users.CreateChildPermission(AppPermissions.Pages_Administration_Users_Edit, L("EditingUser"));
            users.CreateChildPermission(AppPermissions.Pages_Administration_Users_Delete, L("DeletingUser"));
            users.CreateChildPermission(AppPermissions.Pages_Administration_Users_ChangePermissions, L("ChangingPermissions"));
            users.CreateChildPermission(AppPermissions.Pages_Administration_Users_Impersonation, L("LoginForUsers"));

            var languages = administration.CreateChildPermission(AppPermissions.Pages_Administration_Languages, L("Languages"));
            languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Create, L("CreatingNewLanguage"));
            languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Edit, L("EditingLanguage"));
            languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_Delete, L("DeletingLanguages"));
            languages.CreateChildPermission(AppPermissions.Pages_Administration_Languages_ChangeTexts, L("ChangingTexts"));

            administration.CreateChildPermission(AppPermissions.Pages_Administration_AuditLogs, L("AuditLogs"));

            var organizationUnits = administration.CreateChildPermission(AppPermissions.Pages_Administration_OrganizationUnits, L("OrganizationUnits"));
            organizationUnits.CreateChildPermission(AppPermissions.Pages_Administration_OrganizationUnits_ManageOrganizationTree, L("ManagingOrganizationTree"));
            organizationUnits.CreateChildPermission(AppPermissions.Pages_Administration_OrganizationUnits_ManageMembers, L("ManagingMembers"));

            administration.CreateChildPermission(AppPermissions.Pages_Administration_UiCustomization, L("VisualSettings"));

            //TENANT-SPECIFIC PERMISSIONS

            pages.CreateChildPermission(AppPermissions.Pages_Tenant_Dashboard, L("Dashboard"), multiTenancySides: MultiTenancySides.Tenant);

            administration.CreateChildPermission(AppPermissions.Pages_Administration_Tenant_Settings, L("Settings"), multiTenancySides: MultiTenancySides.Tenant);
            administration.CreateChildPermission(AppPermissions.Pages_Administration_Tenant_SubscriptionManagement, L("Subscription"), multiTenancySides: MultiTenancySides.Tenant);

            //HOST-SPECIFIC PERMISSIONS

            var editions = pages.CreateChildPermission(AppPermissions.Pages_Editions, L("Editions"), multiTenancySides: MultiTenancySides.Host);
            editions.CreateChildPermission(AppPermissions.Pages_Editions_Create, L("CreatingNewEdition"), multiTenancySides: MultiTenancySides.Host);
            editions.CreateChildPermission(AppPermissions.Pages_Editions_Edit, L("EditingEdition"), multiTenancySides: MultiTenancySides.Host);
            editions.CreateChildPermission(AppPermissions.Pages_Editions_Delete, L("DeletingEdition"), multiTenancySides: MultiTenancySides.Host);

            var tenants = pages.CreateChildPermission(AppPermissions.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);
            tenants.CreateChildPermission(AppPermissions.Pages_Tenants_Create, L("CreatingNewTenant"), multiTenancySides: MultiTenancySides.Host);
            tenants.CreateChildPermission(AppPermissions.Pages_Tenants_Edit, L("EditingTenant"), multiTenancySides: MultiTenancySides.Host);
            tenants.CreateChildPermission(AppPermissions.Pages_Tenants_ChangeFeatures, L("ChangingFeatures"), multiTenancySides: MultiTenancySides.Host);
            tenants.CreateChildPermission(AppPermissions.Pages_Tenants_Delete, L("DeletingTenant"), multiTenancySides: MultiTenancySides.Host);
            tenants.CreateChildPermission(AppPermissions.Pages_Tenants_Impersonation, L("LoginForTenants"), multiTenancySides: MultiTenancySides.Host);

            administration.CreateChildPermission(AppPermissions.Pages_Administration_Host_Settings, L("Settings"), multiTenancySides: MultiTenancySides.Host);
            administration.CreateChildPermission(AppPermissions.Pages_Administration_Host_Maintenance, L("Maintenance"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
            administration.CreateChildPermission(AppPermissions.Pages_Administration_HangfireDashboard, L("HangfireDashboard"), multiTenancySides: _isMultiTenancyEnabled ? MultiTenancySides.Host : MultiTenancySides.Tenant);
            administration.CreateChildPermission(AppPermissions.Pages_Administration_Host_Dashboard, L("Dashboard"), multiTenancySides: MultiTenancySides.Host);

            #endregion

            #region 自定义权限

            var APJ = context.GetPermissionOrNull(AppPermissions.APJ)
                ?? context.CreatePermission(AppPermissions.APJ, L(AppPermissions.APJ));

            //系统管理
            var system = APJ.CreateChildPermissionByPermissionName(AppPermissions.APJ_System);
            system.CreateChildPermissionByPermissionName(AppPermissions.APJ_System_Role);
            system.CreateChildPermissionByPermissionName(AppPermissions.APJ_System_User);
            system.CreateChildPermissionByPermissionName(AppPermissions.APJ_System_Organizations);
            system.CreateChildPermissionByPermissionName(AppPermissions.APJ_System_Notices);
            system.CreateChildPermissionByPermissionName(AppPermissions.APJ_System_Logs);

            //项目管理
            var project = APJ.CreateChildPermissionByPermissionName(AppPermissions.APJ_Project);
            project.CreateChildPermissionByPermissionName(AppPermissions.APJ_Project_Manage);
            project.CreateChildPermissionByPermissionName(AppPermissions.APJ_Project_Check);

            //企业资料库管理
            var organizationsDocumentLibrarys = APJ.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys);
            organizationsDocumentLibrarys.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys_Up);
            organizationsDocumentLibrarys.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys_NewFolder);
            organizationsDocumentLibrarys.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys_Edit);
            organizationsDocumentLibrarys.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys_Delete);
            organizationsDocumentLibrarys.CreateChildPermissionByPermissionName(AppPermissions.APJ_Organizations_DocumentLibrarys_Move);

            //项目内部权限管理
            var projectInternal = APJ.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Models);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Drawings);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Up);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_NewFolder);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Edit);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Delete);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Move);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_View);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_CheckItems);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_CreateSelf);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_ViewSelf);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_ProjectUser);
            projectInternal.CreateChildPermissionByPermissionName(AppPermissions.APJ_PI_Logs);

            //建委开放接口访问权限
            var AMJ = context.GetPermissionOrNull(AppPermissions.AMJ)
                ?? context.CreatePermission(AppPermissions.AMJ, L(AppPermissions.AMJ));
            var jianwei = AMJ.CreateChildPermissionByPermissionName(AppPermissions.AMJ_Jianwei);

            #endregion
        }

        private static ILocalizableString L(string name)
        {
            return AppAuthorizationProviderExtension.L(name);
        }
    }

    public static class AppAuthorizationProviderExtension
    {
        public static Permission CreateChildPermissionByPermissionName(this Permission p, string name)
        {
            return p.CreateChildPermission(name, L(name.Replace(".", "_")));
        }

        public static ILocalizableString L(string name)
        {
            return new LocalizableString(name, HostConsts.LocalizationSourceName);
        }
    }
}
